package io.cici.cc.mybatis.lite.mapping;

import io.cici.cc.mybatis.lite.reflection.MetaDataObject;
import io.cici.cc.mybatis.lite.reflection.PropertyTokenizer;
import io.cici.cc.mybatis.lite.session.Configuration;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * An actual SQL String got from an {@link SqlSource} after having processed any
 * dynamic content. The SQL may have SQL placeholders "?" and a list (ordered)
 * of a parameter mappings with the additional information for each parameter
 * (at least the property name of the input object to read the value from).
 * <p>
 * Can also have additional parameters that are created by the dynamic language
 * (for loops, bind...).
 */
@Slf4j
@Setter
@Getter
public class Sql {

    private final String sql;
    private final List<ParameterMapping> parameterMappingList;
    private final Object parameterObject;
    private final Map<String, Object> additionalParameters;
    private final MetaDataObject metaParameters;

    public Sql(Configuration configuration, String sql, List<ParameterMapping> parameterMappingList,
               Object parameterObject) {
        this.sql = sql;
        this.parameterMappingList = parameterMappingList;
        this.parameterObject = parameterObject;
        this.additionalParameters = new HashMap<>();
        this.metaParameters = configuration.newMetaDataObject(additionalParameters);
    }

    public boolean hasAdditionalParameter(String name) {
        String paramName = new PropertyTokenizer(name).getName();
        return additionalParameters.containsKey(paramName);
    }

    public void setAdditionalParameter(String name, Object value) {
        metaParameters.setValue(name, value);
    }

    public Object getAdditionalParameter(String name) {
        return metaParameters.getValue(name);
    }

}
